package fr.alesia.deepstack.data.jdo;

import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.jdo.Extent;

import fr.alesia.deepstack.bean.Player;
import fr.alesia.deepstack.bean.Ranking;
import fr.alesia.deepstack.bean.Tournament;
import fr.alesia.deepstack.bean.jdo.RankingJdo;
import fr.alesia.deepstack.data.DataAccessObject;
import fr.alesia.deepstack.data.PlayerDao;
import fr.alesia.deepstack.data.RankingDao;
import fr.alesia.deepstack.data.TournamentDao;
import fr.alesia.deepstack.factory.DaoFactory;

public class RankingDaoJdo extends AbstractDao implements DataAccessObject, RankingDao {

	private static RankingDao instance = null;
	
	private RankingDaoJdo(){}
	
	public static RankingDao getInstance(){
		if(instance == null){		
			instance = new RankingDaoJdo();
		}
		return instance;
	}

	public Ranking find(String id) {

		open();
		RankingJdo ranking = manager.getObjectById(RankingJdo.class, id);
		this.unserialize(ranking);
		close();
		return ranking;
	}

	public SortedSet<Ranking> findAll() {
		
		open();
		Set<Ranking> rankings = new HashSet<Ranking>(500);	
		Extent<RankingJdo> extent = manager.getExtent(RankingJdo.class);
		for (RankingJdo ranking : extent) {
			
			this.unserialize(ranking);
			rankings.add(ranking);
		}
		extent.closeAll();
		extent = null;
		return new TreeSet<Ranking>(rankings);
	}

	public SortedSet<Ranking> findByPlayer(Player player) {

		Set<Ranking> rankings = new HashSet<Ranking>(500);
		Set<Ranking> all = this.findAll();
		for (Ranking ranking : all) {
			
			if(ranking.getPlayer().equals(player)){
				rankings.add(ranking);
			}
		}
		all = null;
		return new TreeSet<Ranking>(rankings);
	}

	public SortedSet<Ranking> findByTournament(Tournament tournament) {

		Set<Ranking> rankings = new HashSet<Ranking>(500);	
		Set<Ranking> all = this.findAll();
		for (Ranking ranking : all) {
			
			if(ranking.getTournament().equals(tournament)){
				rankings.add(ranking);
			}
		}
		all = null;
		return new TreeSet<Ranking>(rankings);
	}
	
	public Ranking find(Tournament tournament, Player player) {
		
		Set<Ranking> rankings = this.findByTournament(tournament);
		for (Ranking ranking : rankings) {
			
			if(ranking.getPlayer().equals(player)){
				
				return ranking;
			}
		}
		return null;
	}

	public void insert(Ranking ranking) {
		
		ranking.setId((ranking.getId() == null ? "k" + ranking.hashCode() : ranking.getId()));
		open();
		manager.makePersistent(ranking);
		close();
	}

	public void update(Ranking ranking) {
		
		open();
		RankingJdo base = manager.getObjectById(RankingJdo.class, ranking.getId());
		base.setPlayer(ranking.getPlayer());
		base.setTournament(ranking.getTournament());
		base.setRank(ranking.getRank());
		manager.makePersistent(base);
		close();
	}

	public void delete(Ranking ranking) {
		
		open();
		Ranking base = this.find(ranking.getId());
		manager.deletePersistent(base);
		close();	
	}
	
	private void unserialize(RankingJdo ranking){
		
		PlayerDao playerDao = DaoFactory.getPlayerDao();
		TournamentDao tournamentDao = DaoFactory.getTournamentDao();
		
		String playerId = ranking.getPlayerId();
		String tournamentId = ranking.getTournamentId();

		Player player = playerDao.find(playerId);
		Tournament tournament = tournamentDao.find(tournamentId);
		
		ranking.setPlayer(player);
		ranking.setTournament(tournament);
		
		player = null;
		tournamentId = null;
		tournament = null;
		playerId = null;
		tournamentDao = null;
		playerDao = null;
	}
	
	
}
